<?php
/**
 * Created by PhpStorm.
 * User: EZ
 * Date: 2017/6/5
 * Time: 9:26
 */
namespace core;
use lib\Redis;
class Route{
    static $model=null;
    static $action=null;
    static $contro=null;
    public  $c_path=null;
    public  $a_path=null;
    public  $m_path=null;
    public $data=null;
    static $debug=true;
    protected static $instance=null;
    public function __construct()
    {
        $this->data=null;
    }

    public function aa(){
        $path=Request::instance()->path();
    }

    /**
     * @return Route|null
     * 解析路由，apache服务器环境下，$_SERVER['PATH_INFO']不是一定有的，需要isset()判断，
     * nginx服务器下$_SERVER['PATH_INFO']是一定有的
     *
     */
    public static function route(){
         $config=self::init();
         Log::record('aaa','info');
         $path=isset($_SERVER['PATH_INFO'])?explode('/',trim($_SERVER['PATH_INFO'],'/')):[];
         $m=array_shift($path);
         self::$model=$m?strtolower($m):'index';
         $c=array_shift($path);
         self::$contro=$c?ucfirst($c):'Index';
         $a=array_shift($path);
         self::$action=$a?$a:'index';
         $ar=[];
         for($i=0;$i<count($path);$i++){
            if($i%2 ==0){
                $ar[$path[$i]]=isset($path[$i+1])?$path[$i+1]:'';
            }
         }
         $_GET=array_merge($_GET,$ar);
        return self::instance();
    }
    public static function run(){

        $config=self::init();
        Log::record("aaaa",'info');
        $path_ar=[];
        if($_SERVER['REQUEST_URI'] && $_SERVER['REQUEST_URI']!='/'){
            $path_url=$_SERVER['REQUEST_URI'];
            if(strpos($path_url,'/index.php')==0){
                $path_url=substr($path_url,10);
            }
            $path_ar=explode('/',trim($path_url,'/'));

            if(!empty($path_ar[0])){
                self::$model=strtolower($path_ar[0]);
                unset($path_ar[0]);
            }else{
                self::$model='index';
            }
            if(!empty($path_ar[1])){
                self::$contro=ucfirst(strtolower($path_ar[1]));
                unset($path_ar[1]);
            }else{
                self::$contro="Index";
            }
            if(!empty($path_ar[2])){
                self::$action=strtolower($path_ar[2]);
                unset($path_ar[2]);
            }else{
                self::$action="index";
            }
        }else{
            self::$model='index';
            self::$contro='Index';
            self::$action='index';
        }
//       echo self::$model.'--'.self::$contro.'--'.self::$action;

        $path_arr=[];

        foreach($path_ar as $k=>$v){
            $path_arr[]=$v;
        }
        for($i=0;$i<=count($path_arr);$i++){
            if($i%2 ==0 && isset($path_arr[$i+1])){
                if(strpos($path_arr[$i+1],"?")){
                    $a=explode("?",$path_arr[$i+1]);
                    $path_arr[$i+1]=$a[0];
                }
                $_GET[$path_arr[$i]]=$path_arr[$i+1];
            }
        }
        return self::instance();
    }

    public  function exe(){

        $class_path="app\\".self::$model."\\controller\\".self::$contro;
        $reflect=new \ReflectionClass($class_path);
        $refObj=$reflect->newInstance();
        try{
            if(!$reflect->hasMethod(self::$action)){
                throw new \Exception("访问了一个不存在的方法:".self::$action);
            }
        }catch (\Exception $e){
            echo $e->getMessage();die;
        }

        if($action=$reflect->getMethod(self::$action)){
            if($action->isPublic() && !$action->isAbstract()){
                $refObj->c_path=self::$contro;
                $refObj->a_path=self::$action;
                $refObj->m_path=self::$model;
                $action->invoke($refObj);
            }
        }
    }

    public function display($view_path=''){
        if(!empty($this->data)){
            extract($this->data);
        }
        if($view_path==''){
            $view_path=$this->a_path;
        }
        $html_file=HTML_PATH.$this->m_path.'/'.$this->c_path.'/'. $view_path.'.html';
        if(!file_exists($html_file)) die("模板不存在".$html_file);
        require $html_file;
    }

    public function assign($key,$val=''){
        if(is_array($key)){
            $this->data=array_merge($this->data,$key);
        }else{
            $this->data[$key]=$val;
        }
    }

    public function _empty(){
        header("HTTP/1.1 404 Not Found");
        echo "该方法不存在";
    }

    public static function instance(){
        if(self::$instance==null){
            self::$instance=new static();
            return self::$instance;
        }else{
            return self::$instance;
        }

    }

    public static function hproseServer(){
        return  new \Hprose\Http\Server();
    }

    public static function hproseClient($url,$p=false){
        $client= \Hprose\Client::create($url,$p);
        return $client;
    }

    //获取配置参数
    public static function config($model=''){
        $model=$model?$model."/":'';

        if(is_file(ZDW_PATH."common/config.php")){
            Config::load(ZDW_PATH."common/config.php",'config');
        }

        if(is_file(ZDW_PATH."common/db.php")){
            Config::load(ZDW_PATH."common/db.php",'db');
        }

        if(is_file(APP_PATH.$model."common/config.php")){
            Config::load(APP_PATH.$model."common/config.php",'config');
        }

        if(is_file(APP_PATH.$model."common/db.php")){
            $a= include APP_PATH.$model."common/db.php";

            Config::load(APP_PATH.$model."common/db.php",'db');
        }

        if(is_file(ZDW_PATH."common/help.php")){
            include ZDW_PATH."common/help.php";
        }
        if(is_file(APP_PATH.$model."common/help.php")){
            include APP_PATH.$model."common/help.php";
        }

        return Config::get();
    }

    //初始化
    public static function init($model=''){
        $config=self::config($model);

         date_default_timezone_set($config['config']['default_timezone']);
        return Config::get();
    }

    public  function getRedis($config=[]){
        $re=Redis::instance($config);
        $re->connect();
        return $re;
    }

    /**
     * URL路由检测（根据PATH_INFO)
     * @access public
     * @param  \core\Request $request
     * @param  array          $config
     * @return array
     * @throws \core\Exception
     */
    public static function routeCheck($request, array $config)
    {
        $path   = $request->path();
        $depr   = $config['pathinfo_depr'];//路由分隔符
        $result = false;
        // 路由检测
            $result = self::parseUrl($path, $depr);

        return $result;
    }

    /**
     * 解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2...
     * @access public
     * @param string    $url URL地址
     * @param string    $depr URL分隔符
     * @param bool      $autoSearch 是否自动深度搜索控制器
     * @return array
     */
    public static function parseUrl($url, $depr = '/', $autoSearch = false)
    {
        $url              = str_replace($depr, '|', $url);
        list($path, $var) = self::parseUrlPath($url);
        $route            = [null, null, null];
        if (isset($path)) {
            // 解析模块
            $module = Config::get('config.app_multi_module') ? array_shift($path) : null;
            if ($autoSearch) {
                // 自动搜索控制器
                $dir    = APP_PATH . ($module ? $module . DS : '') . Config::get('url_controller_layer');

                $item   = [];
                $find   = false;
                foreach ($path as $val) {
                    $item[] = $val;
                    $file   = $dir . DS . str_replace('.', DS, $val)  . EXT;
                    $file   = pathinfo($file, PATHINFO_DIRNAME) . DS . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . EXT;
                    if (is_file($file)) {
                        $find = true;
                        break;
                    } else {
                        $dir .= DS . Loader::parseName($val);
                    }
                }
                if ($find) {
                    $controller = implode('.', $item);
                    $path       = array_slice($path, count($item));
                } else {
                    $controller = array_shift($path);
                }
            } else {
                // 解析控制器
                $controller = !empty($path) ? array_shift($path) : null;

            }
            // 解析操作
            $action = !empty($path) ? array_shift($path) : null;

            // 解析额外参数
            self::parseUrlParams(empty($path) ? '' : implode('|', $path));
            // 封装路由
            $route = [$module, $controller, $action];
            // 检查地址是否被定义过路由
            $name  = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action);

            $name2 = '';
            if (empty($module) || isset($bind) && $module == $bind) {
                $name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action);
            }

            if (isset(self::$rules['name'][$name]) || isset(self::$rules['name'][$name2])) {
                throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url));
            }
        }
        return ['type' => 'module', 'module' => $route];
    }
    private static function parseUrlPath($url)
    {
        // 分隔符替换 确保路由定义使用统一的分隔符
        $url = str_replace('|', '/', $url);
        $url = trim($url, '/');
        $var = [];
        if (false !== strpos($url, '?')) {
            // [模块/控制器/操作?]参数1=值1&参数2=值2...
            $info = parse_url($url);

            $path = explode('/', $info['path']);

            parse_str($info['query'], $var);

        } elseif (strpos($url, '/')) {
            // [模块/控制器/操作]
            $path = explode('/', $url);

        } else {
            $path = [$url];
        }

        return [$path, $var];
    }



}